package controle.acesso.dao;


import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import controle.acesso.model.Funcionalidade;
import controle.acesso.model.UseCase;

import utils.Constantes;
import utils.Utils;

public class FuncionalidadeDao extends GenericDao{
	


private int numerodecampos = 3;
	
	public FuncionalidadeDao(){
		super();
	}


public PreparedStatement adicionar(Funcionalidade funcionalidade) throws SQLException{
		
		String sql = "insert into funcionalidade(acao,descricao,idusecase) values (?,?,?)";
		this.setQuery(sql);
		ArrayList<Integer> indexes=new ArrayList<Integer>();
		for (int i=0;i<numerodecampos;i++)
			indexes.add(i,i+1);
		indexes.add(numerodecampos,null);
		
		PreparedStatement stmt = this.loadModelToPreparedStatement(funcionalidade,indexes);
		
		stmt.execute();	
		this.setQuery(stmt.toString());

		stmt.close();
		
		con.close();
		return stmt;
		
	}	

public PreparedStatement desativar(Funcionalidade funcionalidade) throws SQLException{
	
	String sql = "update funcionalidade set ativo = 'N' where idfuncionalidade = ?";
	this.setQuery(sql);
	ArrayList<Integer> indexes=new ArrayList<Integer>();
	for (int i=0;i<numerodecampos;i++)
		indexes.add(i,null);
	indexes.add(numerodecampos,1);
	PreparedStatement stmt = this.loadModelToPreparedStatement(funcionalidade, indexes);
	
	stmt.execute();
	this.setQuery(stmt.toString());

	stmt.close();
	
	con.close();
	return stmt;
	
	

}

public PreparedStatement ativar(Funcionalidade funcionalidade) throws SQLException{
	
	String sql = "update funcionalidade set ativo = 'S' where idfuncionalidade = ?";
	this.setQuery(sql);
	ArrayList<Integer> indexes=new ArrayList<Integer>();
	for (int i=0;i<numerodecampos;i++)
		indexes.add(i,null);
	indexes.add(numerodecampos,1);
	PreparedStatement stmt = this.loadModelToPreparedStatement(funcionalidade, indexes);
	
	stmt.execute();
	this.setQuery(stmt.toString());

	stmt.close();
	
	con.close();
	return stmt;
	
	

}


	public PreparedStatement apagar(Funcionalidade funcionalidade) throws SQLException{
	String sql = "delete from funcionalidade where idfuncionalidade = ?";
	this.setQuery(sql);
	
	ArrayList<Integer> indexes=new ArrayList<Integer>();
	for (int i=0;i<numerodecampos;i++)
		indexes.add(i,null);
	indexes.add(numerodecampos,1);
	
	PreparedStatement stmt = this.loadModelToPreparedStatement(funcionalidade, indexes);
	
	stmt.execute();
	this.setQuery(stmt.toString());

	stmt.close();
	
	con.close();
	return stmt;
	
	

}

public PreparedStatement alterar(Funcionalidade funcionalidade) throws SQLException{
	
	String sql = "update funcionalidade set acao = ?,descricao = ?,idusecase = ?" +
			" where idfuncionalidade = ? and ativo = 'S'";
	this.setQuery(sql);
	ArrayList<Integer> indexes=new ArrayList<Integer>();
	for (int i=0;i<=numerodecampos;i++)
		indexes.add(i,i+1);
	
	PreparedStatement stmt =this.loadModelToPreparedStatement(funcionalidade,indexes); 
	
	stmt.execute();
	
	this.setQuery(stmt.toString());

	stmt.close();
	
	con.close();
	return stmt;
	
}

public Integer countGetFuncionalidades(Funcionalidade funcionalidadeBusca) throws SQLException{
	if (funcionalidadeBusca==null) return null;
	String sql = "select count(*) as count from funcionalidade where 1=1";		
	this.setQuery(sql);
	this.addAtivo(funcionalidadeBusca.getAtivo().charAt(0));
	ArrayList<Integer> restrictions=this.prepareRestrictionsQuery(funcionalidadeBusca);
	
	PreparedStatement stmt =this.addRestrictions(funcionalidadeBusca, restrictions);
			
	ResultSet rs = stmt.executeQuery();
	Integer count = new Integer(0);
	
	while(rs.next()){
		if (!Utils.isBlank(rs.getInt(Constantes.COUNT)))
			count=rs.getInt(Constantes.COUNT);
	} 
	this.setQuery(stmt.toString());

	stmt.close();
	rs.close();
	con.close();
	
	return count;
}




public ArrayList<Funcionalidade> getFuncionalidades(Funcionalidade funcionalidadeBusca, int limite, int inicio) throws SQLException{
	if (funcionalidadeBusca==null) return null;
	String sql = "select * from funcionalidade where 1=1";		
	this.setQuery(sql);
	this.addAtivo(funcionalidadeBusca.getAtivo().charAt(0));
	ArrayList<Integer> restrictions=this.prepareRestrictionsQuery(funcionalidadeBusca);
	this.addLimit(limite,inicio);
	
	PreparedStatement stmt =this.addRestrictions(funcionalidadeBusca, restrictions);
			
	ResultSet rs = stmt.executeQuery();
	Funcionalidade funcionalidade = null;
	ArrayList<Funcionalidade> funcionalidades=new ArrayList<Funcionalidade>();
	
	while(rs.next()){
		funcionalidade = this.loadResultSetToModel(rs);
		funcionalidades.add(funcionalidade);
		
	} 
	this.setQuery(stmt.toString());

	stmt.close();
	rs.close();
	con.close();
	
	return funcionalidades;
}





private PreparedStatement addRestrictions(Funcionalidade funcionalidade,
		ArrayList<Integer> restrictions) throws SQLException {
PreparedStatement stmt=con.prepareStatement(this.getQuery());
	
	if (!Utils.isBlank(restrictions.get(0)))
		stmt.setString(restrictions.get(0), "%"+funcionalidade.getAcao()+"%");
	
	if (!Utils.isBlank(restrictions.get(1)))
		stmt.setString(restrictions.get(1), "%"+funcionalidade.getDescricao()+"%");
	
	if (!Utils.isBlank(restrictions.get(2)))
		stmt.setInt(restrictions.get(2), funcionalidade.getUseCase().getId());
	
	if (!Utils.isBlank(restrictions.get(3)))
		stmt.setInt(restrictions.get(3), funcionalidade.getId());
	return stmt;
}





private PreparedStatement loadModelToPreparedStatement(Funcionalidade funcionalidade ,ArrayList<Integer> indexes) throws SQLException{
	PreparedStatement stmt=con.prepareStatement(this.getQuery());
	
	if (!Utils.isBlank(indexes.get(0)))
		stmt.setString(indexes.get(0), funcionalidade.getAcao());
	
	if (!Utils.isBlank(indexes.get(1)))
		stmt.setString(indexes.get(1), funcionalidade.getDescricao());
	
	if (!Utils.isBlank(indexes.get(2)))
		stmt.setInt(indexes.get(2), funcionalidade.getUseCase().getId());
	
	if (!Utils.isBlank(indexes.get(3)))
		stmt.setInt(indexes.get(3), funcionalidade.getId());	
	return stmt;
}


private Funcionalidade loadResultSetToModel(ResultSet rs) throws SQLException {
	Funcionalidade funcionalidade = new Funcionalidade();
	
	if (!Utils.isBlank(rs.getInt(Constantes.IDFUNCIONALIDADE)))
		funcionalidade.setId(rs.getInt(Constantes.IDFUNCIONALIDADE));
	
	if (!Utils.isBlank(rs.getString(Constantes.NOME)))
		funcionalidade.setAcao(rs.getString(Constantes.NOME));
	
	if (!Utils.isBlank(rs.getString(Constantes.DESCRICAO)))
		funcionalidade.setDescricao(rs.getString(Constantes.DESCRICAO));
	
	UseCase useCase = new UseCase();
	if (!Utils.isBlank(rs.getInt(Constantes.IDUSECASE)))
		useCase.setId(rs.getInt(Constantes.IDUSECASE));
	UseCaseDao useCaseDao = new UseCaseDao();
	funcionalidade.setUseCase(useCaseDao.getUseCases(useCase, 0, 0).get(0));
	
	
	if (!Utils.isBlank(rs.getString(Constantes.ATIVO)))
		funcionalidade.setAtivo(rs.getString(Constantes.ATIVO));
	
	return funcionalidade;
}





private ArrayList<Integer> prepareRestrictionsQuery(Funcionalidade funcionalidade){
	ArrayList<Integer> restrictions=new ArrayList<Integer>();
	int index=0;
	String sql=this.getQuery();
	
	restrictions.add(0, null);
	if (!Utils.isBlank(funcionalidade.getAcao())){
		sql+=" and acao like ?";
		index++;
		restrictions.add(0, index);
	}
	
	
	restrictions.add(1, null);
	if (!Utils.isBlank(funcionalidade.getDescricao())){
		sql+=" and descricao like ?";
		index++;
		restrictions.add(1, index);
	}
	
	restrictions.add(2, null);
	if ((!Utils.isBlank(funcionalidade.getUseCase())) &&
		(!Utils.isBlank(funcionalidade.getUseCase().getId()))){ 	
		sql+=" and idusecase = ?";
		index++;
		restrictions.add(2, index);
	}
	
	restrictions.add(3, null);
	if (!Utils.isBlank(funcionalidade.getId())){
		sql+=" and idfuncionalidade = ?";
		index++;
		restrictions.add(3, index);
	}

		
	this.setQuery(sql);
	return restrictions;
}







}
